package com.qf.medicaldoctoradmin.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.common.entity.User;
import com.qf.common.utils.AliSmsUtils;
import com.qf.common.utils.JwtUtils;
import com.qf.common.utils.RedisUtils;
import com.qf.medicaldoctoradmin.user.dao.UserDao;
import com.qf.medicaldoctoradmin.user.param.LoginParam;
import com.qf.medicaldoctoradmin.user.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * (User)表服务实现类
 *
 * @author makejava
 * @since 2024-11-06 20:11:48
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Resource
    private UserDao userDao;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;


    /**
     * 登录
     * @param loginParam
     * @return
     */
    @Override
    public String login(LoginParam loginParam) {
        User user = userDao.selectByPhone(loginParam.getPhone());
        if (user == null) {
            throw new RuntimeException("手机号输入错误!");
        }

        // 针对前端提交的密码进行md5加密
        String md5Pwd = SecureUtil.md5(loginParam.getPassword());
        if (!user.getPassword().equals(md5Pwd)) {
            throw new RuntimeException("密码错误!");
        }

        // jwt,不需要存入redis
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getId());
        String token = JwtUtils.createJwt(map);

        return token;
    }

    /**
     * 注册
     * @param user
     */
    @Override
    public void register(User user) {
        // User phone = userDao.selectByPhone(user.getPhone());
        User temp = userDao.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getPhone, user.getPhone()));
        if (temp != null) {
            throw new RuntimeException("手机号已存在!");
        }
        if (temp == null) {
            throw new RuntimeException("手机号不能为空");
        }

        // 对用户密码进行MD5加密
        String md5Pwd = SecureUtil.md5(user.getPassword());
        user.setPassword(md5Pwd); // 设置加密后的密码

        // 保存用户信息
        userDao.insert(user);
    }

    /**
     * 查询用户信息
     * @return
     */
    @Override
    public List<User> getAllUser() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        List<User> users = userDao.selectList(queryWrapper);
        return users;
    }

    @Override
    public void sendCode(String phone) {
        if (phone == null) {
            throw new RuntimeException("手机号不能为空");
        }

        // 判断手机号合理化
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            throw new RuntimeException("手机号不合法");
        }

        // 定义验证码请求的限制
        String countKey = phone + ":count";
        String value = (String) RedisUtils.getValue(phone);

        // 检查请求次数
        Integer count = (Integer) RedisUtils.getValue(countKey);
        if (count == null) {
            count = 0;
        }

        if (count < 3) { // 如果请求次数小于3次
            String code = RandomUtil.randomNumbers(4);
            String key = "code:" + phone;
            RedisUtils.setValueTimeout(key, code, 60); // 存储验证码
            System.out.println(code + ", 生成的新验证码");

            // 异步发送短信(线程、mq)
            // threadPoolExecutor.execute(() -> {
            //     AliSmsUtils.sendSms("宋氏集团", "SMS_471690053", phone, code);
            // });


            // 更新请求次数
            RedisUtils.setValueTimeout(countKey, ++count, 600); // 记录请求次数并设置超时为10分钟
        } else {
            throw new RuntimeException("获取验证码频繁，十分钟内最多获取三次");
        }
    }

}

